#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include<sys/select.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<unistd.h>
#include <errno.h>

void deal_web_request_and_parse(char *data) { //客户端不需要绑定IP地址
    int udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
    int enable_select = 1;
    int res;
    char buf[4096];
    fd_set rx_check;
    struct timeval timeout = {
            .tv_usec = 500,
            .tv_sec = 2
    };

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(2021); //发送->2021端口
    server.sin_addr.s_addr = inet_addr("127.0.0.1"); //本机间的进程间通信

    if (setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &enable_select, sizeof(int)) == -1) {
        printf("sys error:%s\n", strerror(errno));
    }

    socklen_t addrlen = sizeof(struct sockaddr);
    res = (int) sendto(udp_fd, data, strlen(data), 0, (struct sockaddr *) &server, addrlen);

    if (res < 0) {
        printf("error=-1"); //网页中显示和使用错误代码处理
        goto ERROR;
    }

    FD_ZERO(&rx_check);
    FD_SET(udp_fd, &rx_check);
    res = select(udp_fd + 1, &rx_check, NULL, NULL, &timeout);

    if (res < 0) {
        printf("error:0"); //监视 readfd 失败
        goto ERROR;
    } else if (res == 0) { //监听超时
        printf("error=1");
        goto ERROR;
    }

    int len = (int) recvfrom(udp_fd, buf, 4096, 0, NULL, NULL);
    if (len == 0) {
        printf("error=-2"); //可以个服务器通信，但是查询不到数据
        goto ERROR;
    } else if (len > 0) {
        printf("%s", buf); //自身端口回环
    }
    ERROR:
    close(udp_fd);
}

int main(void) {
    char * pRequestMethod;
    char * p = NULL;
    int len = 0;

    //这一句一定要加，否则异步访问会出现页面异常;使用默认的POST传输方式,不使用GET的传输方式
    printf("Content-type:text/html;charset=UTF-8;\n\n");
    pRequestMethod = getenv("REQUEST_METHOD");
    if(pRequestMethod == NULL){
        fprintf(stderr,"Web request url is error \n");
    }else if(strstr(pRequestMethod, "POST") != NULL){
        p = getenv("CONTENT_LENGTH");
        if(p != NULL){
            len = atoi(p);
        }else{
            len = 0;
        }
        p = (char*)calloc(len+1,sizeof(char));
        if(p == NULL){
            printf("&malloc error");
            return 0;
        }
        fgets(p, len+1, stdin);
        deal_web_request_and_parse(p);
        free(p);
    }else{
        printf("method is error");
    }

    fflush(stdout);
    return 0;
}